wayland: Use keyboard serial for implicit grab
authorOlivier Fourdan <ofourdan@redhat.com>
Thu, 30 Jun 2016 10:56:21 +0000 (12:56 +0200)
committerMatthias Clasen <mclasen@redhat.com>
Sat, 20 Aug 2016 03:50:14 +0000 (23:50 -0400)
An xdg-popup requires a serial that the compositor will compare against
its own serial and will dismiss the popup if it doesn't match.

gtk+ uses either a pointer or touch serial for its helper function
_gdk_wayland_seat_get_last_implicit_grab_serial() but if the menu is
triggered before the user has had any pointer or touch interaction with
the client, using a keyboard shortcut, there is neither pointer nor
touch serial available, and gtk+ will use 0 as the default.

As a result, the compositor will instantly dismiss the xdg-popup. In
this case, gtk+ should use the keyboard serial instead.

Track keyboard serial as well and use the keyboard serial as the value
if there is no newer pointer or touch serial available.

https://bugzilla.gnome.org/show_bug.cgi?id=768017

gdk/wayland/gdkdevice-wayland.c

index fce4f3b2b23b99894d2236147abd6e0b42a31b41..c13818ec75513ab7df2ecd4c6ee54e026d56b17a 100644 (file)
@@ -184,6 +184,7 @@ struct _GdkWaylandSeat
   gint64 repeat_deadline;
   GSettings *keyboard_settings;
   uint32_t keyboard_time;
+  uint32_t keyboard_key_serial;
 
   struct gtk_primary_selection_device *primary_data_device;
   struct wl_data_device *data_device;
@@ -1992,6 +1993,7 @@ keyboard_handle_key (void               *data,
     return;
 
   seat->keyboard_time = time;
+  seat->keyboard_key_serial = serial;
   seat->repeat_count = 0;
   _gdk_wayland_display_update_serial (display, serial);
   deliver_key_event (data, time, key + 8, state_w);
@@ -4336,7 +4338,7 @@ _gdk_wayland_seat_get_last_implicit_grab_serial (GdkSeat           *seat,
   GdkWaylandSeat *wayland_seat;
   GdkWaylandTouchData *touch;
   GHashTableIter iter;
-  uint32_t serial = 0;
+  uint32_t serial;
 
   wayland_seat = GDK_WAYLAND_SEAT (seat);
   g_hash_table_iter_init (&iter, wayland_seat->touches);
@@ -4344,6 +4346,8 @@ _gdk_wayland_seat_get_last_implicit_grab_serial (GdkSeat           *seat,
   if (sequence)
     *sequence = NULL;
 
+  serial = wayland_seat->keyboard_key_serial;
+
   if (wayland_seat->pointer_info.press_serial > serial)
     serial = wayland_seat->pointer_info.press_serial;